package com.mrper.filedialog.data.adapter

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.annotation.IdRes
import androidx.annotation.LayoutRes
import androidx.annotation.StringRes
import androidx.recyclerview.widget.RecyclerView

/**
 * Created by Jbtm on 2017/4/24.
 * RecyclerAdapter通用数据适配器
 */
abstract class BaseRecyclerAdapter<E>
/**
 * 构造函数
 * @param context 上下文对象
 * *
 * @param itemId 布局ItemId
 * *
 * @param dataSource 数据源
 */
@JvmOverloads constructor(
    val context: Context, @LayoutRes val layoutId: Int,
    dataSource: MutableList<E>? = null
) : RecyclerView.Adapter<BaseRecyclerAdapter.GenericViewHolder>() {

    protected var inflater: LayoutInflater = LayoutInflater.from(context)

    protected var dataSource: MutableList<E>? = null

    var onItemClickListener: OnItemClickListener<E>? = null

    init {
        this.dataSource = dataSource ?: mutableListOf<E>()
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GenericViewHolder {
        val itemView = inflater.inflate(layoutId, parent, false)
        return GenericViewHolder(itemView)
    }

    override fun onBindViewHolder(holder: GenericViewHolder, position: Int) {
        val item = dataSource!![position]
        if (onItemClickListener != null)
            holder.itemView.setOnClickListener {
                onItemClickListener!!.onItemClick(
                    holder,
                    holder.adapterPosition,
                    position,
                    item
                )
            }
        bindValues(holder, holder.adapterPosition, position, item)
    }

    abstract fun bindValues(
        holder: GenericViewHolder,
        viewPosition: Int,
        dataPosition: Int,
        item: E
    )

    override fun getItemCount(): Int = dataSource?.size ?: 0

    /**
     * 添加一条数据
     * @param item 数据项
     * @param isRefresh 是否刷新数据
     */
    @JvmOverloads
    @Synchronized
    fun add(item: E, isRefresh: Boolean = false) {
        dataSource?.add(item)
        if (isRefresh)
            notifyDataSetChanged()
    }

    /**
     * 指定位置添加一条数据
     * @param item 数据项
     * @param position 要添加数据的位置
     * @param isRefresh 是否刷新
     */
    @JvmOverloads
    @Synchronized
    fun add(item: E, position: Int, isRefresh: Boolean = false) {
        dataSource?.add(position, item)
        if (isRefresh)
            notifyDataSetChanged()
    }

    /**
     * 添加一条数据
     * @param items 数据源
     * @param isRefresh 是否刷新数据
     */
    @JvmOverloads
    @Synchronized
    fun add(items: MutableList<E>, isRefresh: Boolean = false) {
        dataSource?.addAll(items)
        if (isRefresh)
            notifyDataSetChanged()
    }

    /**
     * 添加一些数据
     * @param items 数据集合
     * @param isRefresh 是否刷新数据
     */
    @JvmOverloads
    @Synchronized
    fun add(vararg items: E, isRefresh: Boolean = false) {
        dataSource?.addAll(items)
        if (isRefresh)
            notifyDataSetChanged()
    }

    /**
     * 删除一条数据
     * @param item 数据项
     * @param isRefresh 是否刷新数据
     */
    @JvmOverloads
    @Synchronized
    fun remove(item: E, isRefresh: Boolean = false) {
        dataSource?.remove(item)
        if (isRefresh)
            notifyDataSetChanged()
    }

    /**
     * 删除一条指定位置的数据
     * @param position 数据位置
     * @param isRefresh 是否刷新数据
     */
    @JvmOverloads
    @Synchronized
    fun remove(position: Int, isRefresh: Boolean = false) {
        dataSource?.removeAt(position)
        if (isRefresh)
            notifyItemChanged(position)
    }

    /**
     * 删除一些数据
     * @param items 要删除的数据
     * @param isRefresh 是否刷新数据
     */
    @JvmOverloads
    @Synchronized
    fun remove(items: MutableList<E>, isRefresh: Boolean = false) {
        dataSource?.removeAll(items)
        if (isRefresh)
            notifyDataSetChanged()
    }

    /**
     * 更新数据源
     * @param item 数据Item
     * @param position 要更新的位置
     * @param isRefresh 是否刷新数据
     */
    @JvmOverloads
    @Synchronized
    fun update(item: E, position: Int, isRefresh: Boolean = false) {
        dataSource?.set(position, item)
        if (isRefresh)
            notifyItemChanged(position)
    }

    /**
     * 清空数据源
     * @param isRefresh 是否刷新数据，默认：false
     */
    @JvmOverloads
    @Synchronized
    fun clear(isRefresh: Boolean = false) {
        dataSource?.clear()
        if (isRefresh)
            notifyDataSetChanged()
    }

    /**
     * 获取数据项
     * @param position 数据position
     */
    fun getItem(position: Int) = dataSource?.get(position)

    class GenericViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

        fun setText(@IdRes id: Int, text: String) {
            val txt: TextView? = itemView.findViewById(id)
            txt?.text = text
        }

        fun setText(@IdRes id: Int, @StringRes textId: Int, vararg params: Any?) {
            val txt: TextView? = itemView.findViewById(id)
            txt?.text = itemView.context.getString(textId, params)
        }

    }

    interface OnItemClickListener<E> {
        fun onItemClick(holder: GenericViewHolder, viewPosition: Int, dataPosition: Int, item: E)
    }

}